<?php

class importexport_policy_ftp implements importexport_interface_policy {

    public $mode = FTP_BINARY;

    public $ftp_extension = true;

    public function __construct() {
        $this->extension_loaded_ftp();
    }

    public function extension_loaded_ftp() {
        $this->ftp_extension = extension_loaded('ftp') ? true : false;
        if (! $this->ftp_extension) {
            $this->ftpclient = kernel::single('importexport_policy_ftpclient_client');
            $this->mode = 'MODE_BINARY';
        }
        
        return $this->ftp_extension;
    }

    public function connect($params, &$msg) {
        if (! $params['host']) {
            $msg = app::get('importexport')->_('FTP地址必填');
            return false;
        }
        
        $params['port'] = $params['port'] ? $params['port'] : 21;
        $params['timeout'] = $params['timeout'] ? $params['timeout'] : 30;
        if ($this->ftp_extension) {
            $connect = ftp_connect($params['host'], $params['port'], $params['timeout']);
            $this->conn = $connect;
        } else {
            $connect = $this->ftpclient->connect($params['host'], $params['port'], $params['timeout']);
        }
        
        if (! $connect) {
            $msg = app::get('importexport')->_('连接FTP失败，请检查FTP地址或FTP端口');
            return false;
        }
        
        if (! $this->_login($params, $msg)) {
            return false;
        }
        
        $this->changeDirectory($params['dir']);
        
        return true;
    }

    private function _login($params, &$msg) {
        if (! $params['name'] || ! $params['pass']) {
            $msg = app::get('importexport')->_('登录到FTP失败，请检查用户名和密码');
            return false;
        }
        
        if ($this->ftp_extension) {
            $flag = @ftp_login($this->conn, $params['name'], $params['pass']);
        } else {
            $flag = $this->ftpclient->login($params['name'], $params['pass']);
        }
        
        if (! $flag) {
            $msg = app::get('importexport')->_('登录到FTP失败，请检查用户名和密码');
            return false;
        }
        
        return true;
    }

    public function check($params) {
        $params['timeout'] = 5; // 5秒连接失败则检查不通过
        
        if (! $this->connect($params, $msg)) {
            trigger_error($msg, E_USER_ERROR);
            return false;
        }
        
        $tmpFile = tempnam(TMP_DIR, 'importExportTest');
        file_put_contents($tmpFile, 'This is test file');
        $params['remote'] = 'importExportTest';
        $params['local'] = $tmpFile;
        $params['resume'] = 0;
        // 检查上传文件
        if (! $this->push($params, $msg)) {
            trigger_error($msg, E_USER_ERROR);
            return false;
        }
        
        // 检查下载文件
        if (! $this->pull($params, $msg)) {
            trigger_error($msg, E_USER_ERROR);
            return false;
        }
        return true;
    }
 // end function
    public function changeDirectory($dir = null) {
        if ($this->ftp_extension) {
            @ftp_chdir($this->conn, $dir); // 目录错误会返回警告，屏蔽
        } else {
            $this->ftpclient->changeDirectory($dir);
        }
        
        return true;
    }

    public function push($params, &$msg) {
        if ($this->ftp_extension) {
            try {
                $ret = ftp_nb_put($this->conn, $params['remote'], $params['local'], $this->mode, $params['resume']);
                while ($ret == FTP_MOREDATA) {
                    $ret = ftp_nb_continue($this->conn);
                }
            } catch (Exception $e) {
                $ret = $e->getMessage();
            }
        } else {
            $ret = $this->ftpclient->upload($params['local'], $params['remote'], $this->mode, $params['resume']);
        }
        
        if ($ret == FTP_FAILED || ! $ret) {
            $msg = app::get('importexport')->_('上传失败返回信息 ' . var_export($ret, 1));
            return false;
        }
        
        return true;
    }

    public function pull($params, &$msg) {
        if ($this->ftp_extension) {
            $ret = ftp_nb_get($this->conn, $params['local'], $params['remote'], $this->mode, $params['resume']);
            while ($ret == FTP_MOREDATA) {
                $ret = ftp_nb_continue($this->conn);
            }
        } else {
            $ret = $this->ftpclient->download($params['remote'], $params['local'], $this->mode, $params['resume']);
        }
        
        if ($ret == FTP_FAILED || $ret === false) {
            $msg = app::get('importexport')->_('FTP下载文件失败');
            return false;
        }
        
        return true;
    }

    public function size($filename) {
        if ($this->ftp_extension) {
            return ftp_size($this->conn, $filename);
        } else {
            return $this->ftpclient->getFileSize($filename);
        }
    }

    public function delete($filename) {
        if ($this->ftp_extension) {
            $size = $this->size($filename);
            if (! $size || $size == - 1)
                return true;
            return ftp_delete($this->conn, $filename);
        } else {
            return $this->ftpclient->removeFile($filename);
        }
    }
}


